import {
  getBatchInfo,
  getBatchUnitInfo,
  getCriteriaInfo,
  getGradeInfo,
  getUnitInfo,
  addBatchInfo,
  getCriteriaDetailInfo,
  deleteBatchInfo,
  updateBatchInfo,
  getBatchWarningInfo,
  deleteBatchWarningInfo,
  addBatchWarningInfo,
  getPointInfo,
  getPointInfoByParentCode,
  getScoringRules,
  getSchoolInfo,
  getResourceInfo,
  saveScore,
  downloadTemplate,
  upload,
  downloadErrorExcel,
  downloadReport,
  getSchoolResourceInfo,
  getUploadProgress,
  getUnaccomplishedUnit,
  getFinalResource,
  saveFinalScore,
  saveScoreReview,
  sendWarningSMS,
  getRuleItemInfo
} from '@/api/index'
import { Reducer, Effect, Subscription } from 'umi'
import { ResultType } from '@/types/index'
export interface EvaluationType {
  code: string
  content: string
  createTime: string
  criteriaName: string
  desc: string
  grade: string
  name: string
  publishEndDate: string
  publishStartDate: string
  reviewEndDate: string
  reviewStartDate: string
  status: number
  unit: string
  criteriaCode: string
  unitNumber?: number
  warnNumber?: number
}

export interface PointInfoType {
  name: string
  code: string
  point: string
  type: string
  ruleCode: string
  children: PointInfoType[]
}
interface OrganizationType {
  batchCode: string
  unitCode: string
  unitName: string
}

export interface PointDetailType {
  name: string
  code: string
  point: string
  ruleCode?: string
}

interface ScoreRulesType {
  name: string
  code: string
}

export interface schoolInfoType {
  name: string
  code: string
  order: number
  score?: any[]
}
export interface WarnListType {
  id: number
  WarningTime: string
  batchCode: string
  content: string
  unitCode: string
  unitName: string
}

interface ResourceListType {
  id?: number
  schoolName?: string
  files?: any[]
}
export interface EvaluationStateType {
  evaluationList: EvaluationType[]
  organizationList: OrganizationType[]
  criteriaList: any[]
  gradeList: any[]
  unitList: any[]
  evaluationTarget: any[]
  warnList: WarnListType[]
  pointInfo: PointInfoType[]
  pointDetail: PointDetailType[]
  scoreRules: ScoreRulesType[]
  schoolInfo: schoolInfoType[]
  resourceList: ResourceListType
  schoolProgress: any
  unUploadSchool: any[]
  finalResource: any[]
  indicatorDetail: any[]
}
interface EvaluationModelType {
  namespace: string
  state: EvaluationStateType
  reducers: {
    setState: Reducer<EvaluationStateType>
  }
  effects: {
    function_getBatchInfo: Effect
    function_getBatchUnitInfo: Effect
    function_getCriteriaInfo: Effect
    function_getGradeInfo: Effect
    function_getUnitInfo: Effect
    function_addEvaluationInfo: Effect
    function_updateBatchInfo: Effect
    function_getCriteriaDetailInfo: Effect
    function_deleteBatchInfo: Effect
    function_getBatchWarningInfo: Effect
    function_deleteBatchWarningInfo: Effect
    function_addBatchWarningInfo: Effect
    function_getPointInfo: Effect
    function_getPointInfoByParentCode: Effect
    function_getScoringRules: Effect
    function_getSchoolInfo: Effect
    function_getResourceInfo: Effect
    function_saveScore: Effect
    function_downloadTemplate: Effect
    function_upload: Effect
    function_downloadErrorExcel: Effect
    function_downloadReport: Effect
    function_getSchoolResourceInfo: Effect
    function_getUploadProgress: Effect
    function_getUnaccomplishedUnit: Effect
    function_getFinalResource: Effect
    function_saveFinalScore: Effect
    function_saveScoreReview: Effect
    function_sendWarningSMS: Effect
    function_getRuleItemInfo: Effect
  }
}

interface UnitType {
  code: string
  grade: string
  name: string
  parentCode: string
  tag: string
  typeCode: string
  children?: []
}

// 数组转树状
const arrToTree = (arr: UnitType[]) => {
  const newArr: UnitType[] = []
  // 1做一个映射
  const map: any = {}
  arr.forEach((item) => {
    // 为了计算方便，统一添加children
    item.children = []
    // 构建一个字典
    const key = item.code
    map[key] = item
  })

  // 2. 对于arr中的每一项
  arr.forEach((item) => {
    const parent = map[item.parentCode]
    if (parent) {
      //    如果它有父级，把当前对象添加父级元素的children中
      parent.children.push(item)
    } else {
      //    如果它没有父级（pid:''）,直接添加到newArr
      newArr.push(item)
    }
  })

  return newArr
}

export default <EvaluationModelType>{
  namespace: 'evaluationModel',
  state: {
    evaluationList: [],
    organizationList: [],
    criteriaList: [],
    gradeList: [],
    unitList: [],
    evaluationTarget: [],
    warnList: [],
    pointInfo: [],
    pointDetail: [],
    scoreRules: [],
    schoolInfo: [],
    resourceList: {},
    schoolProgress: [],
    unUploadSchool: [],
    finalResource: [],
    indicatorDetail: []
  },
  reducers: {
    setState(state, { payload }) {
      return { ...state, ...payload }
    }
  },
  effects: {
    // 获取管理端评价信息
    *function_getBatchInfo({}, { call, put }) {
      const result: ResultType = yield call(getBatchInfo)
      yield put({
        type: 'setState',
        payload: {
          evaluationList: result.obj
        }
      })
    },
    // 查询评价参与机构信息
    *function_getBatchUnitInfo({ payload: { code }, callback }, { call, put }) {
      const result: ResultType = yield call(getBatchUnitInfo, code)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            organizationList: result.obj
          }
        })
        if (callback) {
          callback(result)
        }
      }
    },
    // 查询评价指标
    *function_getCriteriaInfo({}, { call, put }) {
      const result: ResultType = yield call(getCriteriaInfo)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            criteriaList: result.obj
          }
        })
      }
    },
    // 查询学段
    *function_getGradeInfo({}, { call, put }) {
      const result: ResultType = yield call(getGradeInfo)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            gradeList: result.obj
          }
        })
      }
    },
    // 查询机构
    *function_getUnitInfo({ payload: { grade } }, { call, put }) {
      const result: ResultType = yield call(getUnitInfo, grade)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            unitList: arrToTree(result.obj as any[])
          }
        })
      }
    },
    // 新增评价信息
    *function_addEvaluationInfo({ payload, callback }, { call }) {
      const result: ResultType = yield call(addBatchInfo, payload)
      callback(result)
    },
    // 查询评价指标
    *function_getCriteriaDetailInfo(
      { payload: { criteriaCode } },
      { call, put }
    ) {
      const result: ResultType = yield call(getCriteriaDetailInfo, criteriaCode)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            evaluationTarget: result.obj
          }
        })
      }
    },
    // 修改评价批次信息
    *function_updateBatchInfo({ payload, callback }, { call }) {
      const result: ResultType = yield call(updateBatchInfo, payload)
      callback(result)
    },
    // 删除评价信息
    *function_deleteBatchInfo({ payload: { code }, callback }, { call }) {
      const result: ResultType = yield call(deleteBatchInfo, code)
      callback(result)
    },
    // 查询评价预警信息
    *function_getBatchWarningInfo(
      { payload: { code }, callback },
      { call, put }
    ) {
      const result: ResultType = yield call(getBatchWarningInfo, code)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            warnList: result.obj
          }
        })
        if (callback) {
          callback(result)
        }
      }
    },
    // 删除评价预警信息
    *function_deleteBatchWarningInfo(
      { payload: { id, code }, callback },
      { call }
    ) {
      const result: ResultType = yield call(deleteBatchWarningInfo, id, code)
      callback(result)
    },
    // 新增评价预警信息
    *function_addBatchWarningInfo({ payload, callback }, { call }) {
      const result: ResultType = yield call(addBatchWarningInfo, payload)
      callback(result)
    },
    // 查询打分板指标信息
    *function_getPointInfo({ payload: { batchCode, type } }, { call, put }) {
      const result: ResultType = yield call(getPointInfo, batchCode, type)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            pointInfo: result.obj
          }
        })
      }
    },
    // 查询打分板指标打分点信息
    *function_getPointInfoByParentCode(
      { payload: { batchCode, parentCode, type } },
      { call, put }
    ) {
      const result: ResultType = yield call(
        getPointInfoByParentCode,
        batchCode,
        parentCode,
        type
      )
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            pointDetail: result.obj
          }
        })
      }
    },
    // 打分规则
    *function_getScoringRules({ payload: { ruleCode = '50' } }, { call, put }) {
      const result: ResultType = yield call(getScoringRules, ruleCode)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            scoreRules: result.obj
          }
        })
      }
    },
    // 查询打分板学校信息
    *function_getSchoolInfo(
      { payload: { batchCode, questionCode, grade, unitName } },
      { call, put }
    ) {
      const result: ResultType = yield call(getSchoolInfo, {
        batchCode,
        questionCode,
        grade,
        unitName
      })
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            schoolInfo: result.obj
          }
        })
      }
    },
    // 获取评审资源
    *function_getResourceInfo(
      { payload: { batchCode, userCode, questionCode }, callback },
      { call, put }
    ) {
      const result: ResultType = yield call(
        getResourceInfo,
        batchCode,
        userCode,
        questionCode
      )
      if (result.code === 200) {
        if (!Object.keys(result.obj).length) {
          if (callback) {
            callback(false)
          }
        } else {
          callback(true)
        }
        yield put({
          type: 'setState',
          payload: {
            resourceList: result.obj
          }
        })
      }
    },
    // 保存评审记录
    *function_saveScore(
      {
        payload: { batchCode, type, json, id, unitCode, reviewerCode },
        callback
      },
      { call }
    ) {
      const result: ResultType = yield call(
        saveScore,
        batchCode,
        type,
        json,
        id,
        unitCode,
        reviewerCode
      )
      if (result.code === 200) {
        callback(result)
      }
    },
    *function_saveScoreReview(
      {
        payload: { batchCode, type, json, id, unitCode, reviewerCode },
        callback
      },
      { call }
    ) {
      const result: ResultType = yield call(
        saveScoreReview,
        batchCode,
        type,
        json,
        id,
        unitCode,
        reviewerCode
      )
      if (result.code === 200) {
        callback(result)
      }
    },
    // 下载模板
    *function_downloadTemplate({ payload: { batchCode }, callback }, { call }) {
      const result: ResultType = yield call(downloadTemplate, batchCode)
      callback(result)
    },
    // 量表导入
    *function_upload({ payload: { formData }, callback }, { call }) {
      const result: ResultType = yield call(upload, formData)
      callback(result)
    },
    // 量表导入错误信息下载
    *function_downloadErrorExcel(
      { payload: { batchCode }, callback },
      { call }
    ) {
      const result: ResultType = yield call(downloadErrorExcel, batchCode)
      callback(result)
    },
    // 评价打分结果下载
    *function_downloadReport(
      { payload: { batchCode, unitCode }, callback },
      { call }
    ) {
      const result: ResultType = yield call(downloadReport, batchCode, unitCode)
      callback(result)
    },
    *function_getSchoolResourceInfo(
      { payload: { batchCode, unitCode, questionCode }, callback },
      { call, put }
    ) {
      const result: ResultType = yield call(
        getSchoolResourceInfo,
        batchCode,
        unitCode,
        questionCode
      )
      if (result.code === 200) {
        if (callback) {
          callback(result)
        }

        yield put({
          type: 'setState',
          payload: {
            resourceList: result.obj
          }
        })
      }
    },
    // 学校上传进度查询
    *function_getUploadProgress({ payload: { batchCode } }, { call, put }) {
      const result: ResultType = yield call(getUploadProgress, batchCode)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            schoolProgress: result.obj
          }
        })
      }
    },
    *function_getUnaccomplishedUnit(
      { payload: { batchCode, questionCode } },
      { call, put }
    ) {
      const result: ResultType = yield call(
        getUnaccomplishedUnit,
        batchCode,
        questionCode
      )
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            unUploadSchool: result.obj
          }
        })
      }
    },
    *function_getFinalResource({ payload: { batchCode } }, { call, put }) {
      const result: ResultType = yield call(getFinalResource, batchCode)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            finalResource: result.obj
          }
        })
      } else {
        yield put({
          type: 'setState',
          payload: {
            finalResource: []
          }
        })
      }
    },
    *function_saveFinalScore(
      { payload: { batchCode, unitCode, json }, callback },
      { call }
    ) {
      const result: ResultType = yield call(
        saveFinalScore,
        batchCode,
        unitCode,
        json
      )
      callback(result)
    },
    *function_sendWarningSMS(
      { payload: { unitName, unitCode, date }, callback },
      { call }
    ) {
      const result: ResultType = yield call(
        sendWarningSMS,
        unitName,
        unitCode,
        date
      )
      callback(result)
    },
    *function_getRuleItemInfo({ payload: { ruleCode } }, { call, put }) {
      const result: ResultType = yield call(getRuleItemInfo, ruleCode)
      if (result.code === 200) {
        yield put({
          type: 'setState',
          payload: {
            indicatorDetail: result.obj ?? []
          }
        })
      }
    }
  }
}
